package com.example.javaproject.design.rules;


import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 迪米特法则
 * <p>
 * "只和我的朋友打交到"
 * 一个软件实体应当尽可能少地与其他实体发生相互作用。
 * 迪米特法则又叫最少知道原则，通俗的来讲，就是一个类对自己依赖迪类知道的越少越好。也就是说，对于被依赖的类来说，无论逻辑多么复杂，都尽量的将逻辑封装在类的内部，对外除了提供的public方法，不对外泄漏任何信息
 * <p/>
 */
public class LODTest {

    public static void main(String[] args) {

        // 这里以一个租房子为例，进行说明; 涉及到3个角色，房间，中介，客户，客户通过中介租房子只要求面积和租金

        // 方案1：将房间的比对，放入到租客类中进行
        // 这种方案中，Tenant类和 Room的耦合度太高，当Room类变化时，Tenant类也得跟着变
        Mediator1 m1 = new Mediator1();
        Tenant1 t1 = new Tenant1(72f, 1500f);
        t1.rentRoom(m1);

        // 方案2：将房间的所有操作放入到，Mediator类中，这样过后对租客而已，只和中介打交到，不与房间有任何交互
        Mediator2 m2 = new Mediator2();
        Tenant2 t2 = new Tenant2(10f, 1500f);
        t2.rentRoom(m2);
    }
}


/**
 * 房间
 */
class Room {
    private float area;
    private float price;

    Room(float area, float price) {
        this.area = area;
        this.price = price;
    }

    public float getArea() {
        return area;
    }

    public float getPrice() {
        return price;
    }
}


/**
 * 租客
 */
class Tenant1 {

    private float roomArea;
    private float roomPrice;

    public Tenant1(float roomArea, float roomPrice) {
        this.roomArea = roomArea;
        this.roomPrice = roomPrice;
    }

    /**
     * 找中介租房子
     *
     * @param mediator
     */
    public void rentRoom(Mediator1 mediator) {
        List<Room> allRooms = mediator.getRooms();
        boolean isRentSuccess = false;
        for (Room room : allRooms) {
            if (isFit(room)) {
                isRentSuccess = true;
                System.out.println("成功租到房子，房子面积为" + room.getArea() + ",房子价格为" + room.getPrice());
                break;
            }
        }

        if (!isRentSuccess) {
            System.out.println("没有满足需求的房子");
        }
    }

    /**
     * 是否合适
     *
     * @param room
     * @return
     */
    private boolean isFit(Room room) {
        return room.getArea() == roomArea && room.getPrice() == roomPrice;
    }

}

/**
 * 中介
 */
class Mediator1 {

    private List<Room> rooms = new ArrayList<>(4);

    Mediator1() {
        rooms.add(new Room(80f, 2000f));
        rooms.add(new Room(56f, 1500f));
        rooms.add(new Room(60f, 1800f));
        rooms.add(new Room(72f, 1500f));
    }

    public List<Room> getRooms() {
        return rooms;
    }
}

/**
 * 租客
 */
class Tenant2 {

    private float roomArea;
    private float roomPrice;

    public Tenant2(float roomArea, float roomPrice) {
        this.roomArea = roomArea;
        this.roomPrice = roomPrice;
    }

    /**
     * 找中介租房子
     *
     * @param mediator
     */
    public void rentRoom(Mediator2 mediator) {
        mediator.providerRoom(roomArea, roomPrice);
    }

}

/**
 * 中介
 */
class Mediator2 {

    private List<Room> rooms = new ArrayList<>(4);

    Mediator2() {
        rooms.add(new Room(80f, 2000f));
        rooms.add(new Room(56f, 1500f));
        rooms.add(new Room(60f, 1800f));
        rooms.add(new Room(72f, 1500f));
    }

    public void providerRoom(float targetArea, float targetPrice) {
        boolean isRentSuccess = false;
        for (Room room : rooms) {
            if (isFit(room, targetArea, targetPrice)) {
                isRentSuccess = true;
                System.out.println("成功租到房子，房子面积为" + room.getArea() + ",房子价格为" + room.getPrice());
                break;
            }
        }

        if (!isRentSuccess) {
            System.out.println("没有满足需求的房子");
        }
    }

    private boolean isFit(Room room, float targetArea, float targetPrice) {
        return room.getArea() == targetArea && room.getPrice() == targetPrice;
    }

}


